<?php

namespace app\services\marketing\coupon;

use app\dao\coupon\CouponDao;
use app\services\BaseService;
use app\services\user\UserService;
use exceptions\ApiException;
use jianyan\excel\Excel;
use think\exception\ValidateException;
use think\facade\Db;
use app\services\coupon\CouponUserService;

/**
 * Class Coupon
 * @package app\services\coupon
 */
class CouponService extends BaseService
{
    /**
     * 不导出的字段信息
     * @var array
     */
    protected $noExportFields = ['delete_time', 'update_time', 'is_del'];

    public function __construct(CouponDao $dao)
    {
        $this->dao = $dao;
    }

    public function getCouponTypeList()
    {
        return ['0' => '满减', '1' => '无门槛'];
    }

    public function getUseTypeList()
    {
        return ['0' => '通用', '1' => '技师', '2' => '服务'];
    }

    public function getReceiveTypeList()
    {
        return ['1' => '新人券', '2' => '系统发送', '3' => '会员券', '4' => '积分兑换'];
    }

    public function getIsTimeLimitList()
    {
        return ['0' => '限时', '1' => '不限'];
    }

    public function getIsPermanentList()
    {
        return ['0' => '限制', '1' => '无限制'];
    }

    public function getStatusList()
    {
        return ['0' => '关闭', '1' => '开启'];
    }

    /**
     * Description: 获取分页列表
     *
     * @param array $where
     *
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DataNotFoundException
     * @return array
     */
    public function getList(array $where)
    {
        [$page, $limit] = $this->getPageValue();
        $data  = $this->dao->getList($where, $page, $limit);
        $count = $this->dao->count($where);
        return compact('data', 'count');
    }

    //================接口=====================
    public function getApiList(array $where)
    {
        [$page, $limit] = $this->getPageValue();
        $data  = $this->dao->getApiList($where, $page, $limit, 'id,coupon_title,coupon_price,integral');
        $count = $this->dao->count($where);
        return compact('data', 'count');
    }

    /**
     * Description:平台发送用户未领取优惠券列表
     *
     * @param $uid
     *
     * @throws \ReflectionException
     * @return array
     */
    public function getUnclaimedCouponsList(int $uid)
    {
        /** @var CouponUserService $CouponUserService */
        $CouponUserService = app()->make(CouponUserService::class);
        $user_coupon_ids   = array_keys($CouponUserService->getColumn(['uid' => $uid], 'coupon_id', 'coupon_id'));

        $where['status']       = 1;
        $where['receive_type'] = 2;
        if ($user_coupon_ids) {
            $where['id'] = $user_coupon_ids;
        }
        [$page, $limit] = $this->getPageValue();
        $data  = $this->dao->getApiList($where, $page, $limit, 'id,coupon_price,coupon_type,coupon_title,is_time_limit,start_time,end_time');
        $count = $this->dao->count($where);

        return compact('data', 'count');
    }

    /**
     * Description: 用户领取优惠券
     *
     * @param int $uid
     * @param int $coupon_id
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return bool
     */
    public function receiveCoupon(int $uid, int $coupon_id)
    {
        $data = $this->dao->get($coupon_id, ['business_id', 'coupon_title', 'coupon_price', 'coupon_type', 'use_type', 'use_type_id', 'use_min_price', 'use_days', 'receive_type'])->toArray();
        if (!$this->dao->be($coupon_id))
            throw new ApiException('数据不存在');
        $data['uid']            = $uid;
        $data['coupon_id']      = $coupon_id;
        $data['start_use_time'] = time();
        $data['end_use_time']   = ($data['use_days'] * 86400) + time();
        unset($data['use_days']);
        /** @var CouponUserService $CouponUserService */
        $CouponUserService = app()->make(CouponUserService::class);
        // if ($CouponUserService->be(['coupon_id' => $coupon_id]))
        //     throw new ApiException('库中已存在');
        if (!$CouponUserService->save($data))
            throw new ApiException('写入失败');
        return true;
    }

    /**
     * Description:优惠券兑换专场列表
     *
     * @param array $where
     *
     * @throws \ReflectionException
     * @return array
     */
    public function queryIntegralCouponList(array $where)
    {
        /** @var CouponUserService $CouponUserService */
        $CouponUserService = app()->make(CouponUserService::class);
        $coupon_ids        = $CouponUserService->getIntegralExchangeCouponNumber(['receive_type' => 4]);
        $coupon_ids        = array_column($coupon_ids, null, 'coupon_id');

        [$page, $limit] = $this->getPageValue();
        $data = $this->dao->getApiList($where, $page, $limit, 'id,coupon_title,coupon_price,integral,coupon_image');
        foreach ($data as $k => $v) {
            $data[$k]['receive_number'] = array_key_exists($v['id'], $coupon_ids) ? $coupon_ids[$v['id']]['receive_number'] : 0;
        }
        $count = $this->dao->count($where);
        return compact('data', 'count');
    }

    /**
     * Description:积分兑换优惠券
     *
     * @param array $user
     * @param int   $coupon_id
     *
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @return bool
     */
    public function integralExchangeCoupon($user, int $coupon_id)
    {
        $data = $this->dao->get($coupon_id, ['integral', 'business_id', 'coupon_title', 'coupon_price', 'coupon_type', 'use_type', 'use_type_id', 'use_min_price', 'use_days', 'receive_type'])->toArray();
        if (!$this->dao->be($coupon_id))
            throw new ApiException('数据不存在');
        if ($data['integral'] > $user['integral'])
            throw new ApiException('积分不足');
        $data['uid']            = $user['id'];
        $data['coupon_id']      = $coupon_id;
        $data['start_use_time'] = time();
        $data['end_use_time']   = ($data['use_days'] * 86400) + time();
        $this->transaction(function () use ($data) {
            /** @var UserService $UserService */
            $UserService = app()->make(UserService::class);
            // 扣除积分
            $UserService->setDec(['id' => $data['uid']], 'integral', (int)$data['integral']);
            unset($data['use_days'], $data['integral']);

            /** @var CouponUserService $CouponUserService */
            $CouponUserService = app()->make(CouponUserService::class);
            if (!$CouponUserService->save($data))
                throw new ApiException('写入失败');
        });
        return true;
    }
}
